package proxy.dissem;

import java.util.ArrayList;
import java.util.List;

import proxy.Configuration;
import proxy.Content;
import proxy.HormoneControls;
import proxy.Link;
import proxy.Migration;
import proxy.SearchServerNode;
import proxy.UnitContainer;
import simulation.Simulator;
import consumer.Viewing;

public class GossipServerNode extends SearchServerNode {

	public GossipServerNode(int id, Simulator simulator, Configuration config,
			HormoneControls hCtrl) {
		super(id, simulator, config, hCtrl);
	}

	@Override
	public void diffuseHormones() {
		// nothing to do
	}

	/**
	 * Incoming pull request from neighbor - i have to check whether i have the
	 * requested unit
	 * 
	 * @param g
	 * @param c
	 */
	public void pull(GossipServerNode g, Content c) {
		simulator
				.log(this.getId() + " incoming pull request from " + g.getId());

		ArrayList<UnitContainer> result = searchPresentUnits(c);
		if (result.size() > 0) {
			
			Link l = null;
			if (!this.containsTarget(g)) {
				l = new Link(g, this.getLinks().get(0).getDatarate());
				links.add(l);
				this.getOutgoingUnits().add(new ArrayList<Migration>());
			} else {
				l = getLinkTo(g);
			}
			Migration m = createMigration(result.get(0), 0.0, l);
			// put to outgoing
			getOutgoingUnits().get(links.indexOf(l)).add(m);
			// move
			migrateUnitTo(result.get(0).getVideoUnit(), l, true);

		}
	}

	@Override
	public void decreaseInterest(Viewing vi) {
		// nothing to do here
	}

	@Override
	public boolean performThreeWayCleanupForUnit(int id) {
		return false;
	}

	@Override
	// kommt vom client - also muss ich hier die logik reinbauen
	// send pull request to one random neighbor
	public void increaseInterest(List<Viewing> currentlyDemanding,
			boolean newRequest, boolean sequential) {

		if (currentlyDemanding.size() == 0)
			return;

		// select neighbor to contact
		int neighbor = 0;
		GossipServerNode n = null;
		do {
			neighbor = this.simulator.getRand().nextInt(
					this.simulator.getNodes().size());
			n = (GossipServerNode) simulator.getNodes().get(neighbor);
		} while (n.getId() == this.getId());
		// indicate that you want this unit from the node!
		simulator.log(this.getId() + " sending pull request to " + n.getId());
		//each pull = one message
		simulator.messageCount++;
		n.pull(this, currentlyDemanding.get(0).getVideoUnit().getContent());
	}
}
